home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 6 / QRZ Ham Radio Callsign Database - Volume 6.iso / mac / files / amiga / csrc720j.lzh / samiga.c < prev    next >
C/C++ Source or Header  |  1993-04-17  |  16KB  |  621 lines

  1. /*
  2.  * SAMIGA.C - 19th Aug 1988 - System dependent functions for the
  3.  * single-user SYSOP version of 'mb'.
  4.  * Pete Hardie VE5VA
  5.  *
  6.  */
  7.  
  8. #include "mb.h"
  9. #include <intuition/intuition.h>
  10. #include <intuition/intuitionbase.h>
  11. #include <graphics/text.h>
  12. #include <ctype.h>
  13. #include <time.h>
  14. #include "rexxhostbase.h"
  15.  
  16. extern struct RexxHost      *rexx_host;
  17. extern long rexxbit;
  18. char arexx_port_name[50];
  19. char *arexx_port = 0L;
  20.  
  21.  
  22. extern struct Window *mywindow;
  23. extern struct IntuiMessage *NewMessage;
  24. short debug;
  25. char tmpstr[300];
  26. extern struct IOStdReq *Con_Read,*Con_Write;
  27. extern char optflags[];
  28.  
  29.  
  30. char l_date[7], l_time[5];
  31. char z_date[7], z_time[5];
  32. char pt_flag = 0;
  33. short done_flag = 1;
  34. /*
  35.  *  Set the current I/O device.
  36.  */
  37.  
  38. ioport(pp)
  39. PORTS *pp;
  40. {
  41.   port = pp;
  42. }
  43.  
  44. /*
  45.  *  Return non-zero if a character waits at current input.
  46.  */
  47.  
  48. instat()
  49. {
  50.   register int st;
  51.  
  52.    /* check for char at console */
  53.    if(CheckIO((struct IORequest *)Con_Read))return(1);
  54.    return(0);
  55. }
  56.  
  57. /*
  58.  *  Put the character out the current port,
  59.  *  echo to console if the current port is not the console.
  60.  *  Note special handling of end-of-line character.
  61.  */
  62.  
  63. outchar(ch)
  64. char ch;
  65. {
  66.    if (ch is '\r') return;
  67.    if (ch is '\n') ch = '\r';
  68. /*
  69.  *  Put it out to the console, if it is going there.
  70.  */
  71.  
  72.    if ((port->dev is p_console) or port->ec)   {
  73.       if (ch is '\r') ttputc('\n');/* output '\n' */;
  74.       ttputc(ch);
  75.    }
  76. }
  77. #define PROCLEN 200
  78. unsigned char procstr[PROCLEN];
  79. outstr(cp)
  80. unsigned char *cp;
  81. {
  82.    register unsigned char *p,*q;
  83.    register int beepcount;
  84. if(debug) {
  85.    p = cp;
  86.    while(*p)outchar(*p++);
  87.    return;
  88. }
  89.    if(arexx_port) {
  90.       remnl(cp);
  91. if(debug)printf("Send '%s' to '%s'\n",cp,arexx_port);
  92.       SendRexxMsg((STRPTR)arexx_port,0L,(STRPTR)cp,0L);
  93.       return;
  94.    }
  95.    /* count the number of beeps in the line so that we can give an audible
  96.       as well as visual beep
  97.    */
  98.    if((port->dev is p_console) || port->ec) {
  99.       beepcount = 0;
  100.       for(q = cp,p = &procstr[0];*q && p < &procstr[PROCLEN-1];q++) {
  101.          if(*q is '\r')continue;
  102.          *p++ = *q;
  103.          if(*q == '\007')beepcount++;
  104.       }
  105.       *p = 0;
  106.       Con_Write->io_Data = (APTR) &procstr[0];
  107.       Con_Write->io_Length = p-&procstr[0];
  108.       Con_Write->io_Command = CMD_WRITE;
  109.       DoIO((struct IORequest *)Con_Write);
  110.       while(beepcount--) {
  111.          beep();
  112.          Delay(15L);
  113.       }
  114.    }
  115. }
  116. /* samiga can't talk to the tnc! */
  117. PORTS *devtnc = 0L;
  118. char *inittnc(infile)
  119. char *infile;
  120. {
  121.    return((char *)0);
  122. }
  123. /*
  124. hex(c)
  125. char c;
  126. {
  127.    register char k;
  128.    k = c;
  129.    if((k >= '0') && (k <= '9'))return(k - '0');
  130.    k = toupper(k);
  131.    if((k >= 'A') && (k <= 'F'))return(k - 'A' + 10);
  132.    return(0);
  133. }
  134. */
  135. flipdebug()
  136. {
  137.    debug ^= 1;
  138.    if(debug) {
  139.       ttputs("debug now ON\n");
  140.    }
  141.    else {
  142.       ttputs("debug now OFF\n");
  143.    }
  144. }
  145. extern unsigned char ichar;
  146. extern long keybit,windbit,timerbit;
  147. long getbits;
  148. struct timeRequest {
  149.    struct IORequest tr_node;
  150.    struct timeval tr_time;
  151. };
  152. extern struct timeRequest timermsg;
  153.  
  154. /* replace the original do_idle because it busy-waited ...
  155.    this version sleeps until there is something to do
  156. */
  157. extern short cursecs;
  158. do_idle()
  159. {
  160.    register unsigned char ch,*q;
  161.    register PORTS *p;
  162.    int curmin,curmon;
  163.    ULONG class,waitbits;
  164.    char go_flag;
  165.    USHORT code;
  166.    struct RexxMsg *rexxmessage;  /* incoming rexx messages */
  167.    STRPTR Arg;       /* Temporary string pointer */
  168.  
  169.    arexx_port = 0L;
  170.    cursor_off();
  171.    for(p=porthd; p != NULL; p = p->next) {
  172.       p->ec = p->ecmon;
  173.    }
  174.    ioport(cport);
  175.    /* figure out time to next forward and set timer */
  176.    curtim();
  177.    curmin = 60 - cursecs;
  178.    settimer(curmin);
  179.    /* There might already be an unread char at the serial or console port */
  180.    clrbusy();
  181.    waitbits = windbit | timerbit | keybit | rexxbit;
  182. ttputs("\nIDLE\n");
  183.    while(1)  {
  184.       getbits = Wait(waitbits);
  185.       go_flag = 0;
  186.       /* Although SYSOP has an AREXX port open it does not take commands
  187.          from other AREXX ports. It only gives them
  188.       */
  189.       if(rexxbit & getbits) {
  190.          while(rexxmessage = GetRexxMsg(rexx_host,0L)) {
  191.             if(Arg = GetRexxCommand(rexxmessage)) {
  192.                if(!strncmp((char *)Arg,"GO",2)) {
  193.                   go_flag++;
  194.                   q = (unsigned char *)Arg + 2;
  195.                   while((*q == ' ') || (*q == '\n'))q++;
  196.                   if(*q) {
  197.                      strcpy(arexx_port_name,(char *)q);
  198.                      arexx_port = arexx_port_name;
  199.                   }
  200.                   else {
  201.                      arexx_port = 0L;
  202.                   }
  203.                }
  204.                ReplyRexxCommand(rexxmessage,0L,0L,0L);
  205.                if(go_flag)goto cmd_exit;
  206.             }
  207.             else {
  208.                FreeRexxCommand(rexxmessage);
  209.             }
  210.          }
  211.       }
  212.       if(windbit & getbits) {
  213.          while(NewMessage =
  214.               (struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
  215.             class = NewMessage->Class;
  216.             code = NewMessage->Code;
  217.             ReplyMsg((struct Message *)NewMessage);
  218.             if(class == CLOSEWINDOW) {
  219.                /* say a fond farewell, don't ask fer sure? */
  220.                if(done_flag) {
  221.                   if(timerbit & getbits) {
  222.                      WaitIO((struct IORequest *)&timermsg);
  223.                   }
  224.                   else {
  225.                      cantimer();
  226.                   }
  227.                   SetWindowTitles(mywindow,(UBYTE *)"",(UBYTE *) -1L);
  228.                   /* Need this to cancel out the clrbusy in done() */
  229.                   setbusy();
  230.                   done(1);
  231.                }
  232.             }
  233.          }
  234.       }
  235.       if(getbits & keybit) {
  236.          WaitIO((struct IORequest *)Con_Read);
  237.          ch = ichar;
  238.          Con_Read->io_Data = (APTR)&ichar;
  239.          Con_Read->io_Command = CMD_READ;
  240.          Con_Read->io_Length = 1;
  241.          SendIO((struct IORequest *)Con_Read);
  242.          if(ch == wchar) {
  243. cmd_exit:
  244.             ioport(cport);
  245.             cursor_on();
  246.             /* could have a timerbit set here.
  247.                readbit could also be set but must handle that a
  248.                different way.
  249.             */
  250.             if(timerbit & getbits) {
  251.                WaitIO((struct IORequest *)&timermsg);
  252.             }
  253.             else {
  254.                cantimer();
  255.             }
  256.             return;
  257.          }
  258.          if(ch == '\033') {
  259.             ttputs("do_idle\n");
  260.          }
  261.       }
  262.       /* This code is deliberately placed last. If a timer bit occurs
  263.          at the same time as a character arrives from the serial port
  264.          then this code will hang the serial port up because afwd()
  265.          tries to use the port again without clearing the existing char.
  266.          So workaround it. Putting the timer code here guarantees that
  267.          even if the ser char did occur it will be handled first and the
  268.          ser char code handles the problem of returning from this routine
  269.          with a timer bit set.
  270.       */
  271.       if(timerbit & getbits) {
  272.          WaitIO((struct IORequest *)&timermsg);
  273.          curtim();
  274.          curmin = 10 * (l_time[2] - '0') + (l_time[3] - '0');
  275.          curmon = 10 * (l_date[2] - '0') + (l_date[3] - '0');
  276.          settimer(60);
  277.       }
  278.    }
  279. }
  280. /* replace getdat from mbutil to reduce busy waits */
  281. /* MAXLEN is the longest unterminated line the justification routine
  282.    will accept before it rips out the word and keeps it for later use.
  283.    MAXJUST is the longest word that the routine will keep ... if the word
  284.    is any longer than this then it will just allow you to mess up the line!
  285. */
  286. #define MAXLEN 77
  287. #define MAXJUST 20
  288. unsigned char x_pos = 0; /* Position on line for right justification */
  289. unsigned char s_pos = 0; /* Position of last space on the line */
  290. char saveword[MAXJUST+2];
  291. char *cp;
  292. getdat()
  293. {
  294.  
  295.    register char ch;
  296.    register PORTS *p;
  297.    register char *q;
  298.    int eflag;
  299.    int curmin;
  300.    ULONG class,waitbits;
  301.    USHORT code;
  302.    struct RexxMsg *rexxmessage;  /* incoming rexx messages */
  303.    STRPTR Arg;
  304.  
  305.    x_pos = s_pos = 0;
  306.    p = port;
  307.    cp = p->line;
  308.    *cp = 0;
  309.    /* If there was a justified word left over from previous line .. put it
  310.       in here now.
  311.    */
  312.    if(*saveword) {
  313.       q = saveword;
  314.       while(*q) {
  315.          ttputc(*q);
  316.          *cp++ = *q++;
  317.          x_pos++;
  318.       }
  319.    }
  320.    *saveword = 0;
  321.    /* Is a timeout timer required? */
  322.    curmin = 0;
  323.    if(p->flags & p_dotmr) {
  324.          curmin = p->ctime;
  325.    }
  326.    if(curmin)settimer(curmin);   /* set timeout timer if required */
  327.    p->flags setbit p_dotmr;
  328.  
  329.    waitbits = windbit | timerbit | keybit | rexxbit;
  330.    while(1)  {
  331.       getbits = Wait(waitbits);
  332.       if(windbit & getbits) {
  333.          while(NewMessage =
  334.                     (struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
  335.             class = NewMessage->Class;
  336.             code = NewMessage->Code;
  337.             ReplyMsg((struct Message *)NewMessage);
  338.             if(class == CLOSEWINDOW) {
  339.                /* say a fond farewell, don't ask fer sure? */
  340.                if(done_flag) {
  341.                   if(timerbit & getbits) {
  342.                      WaitIO((struct IORequest *)&timermsg);
  343.                   }
  344.                   else {
  345.                      cantimer();
  346.                   }
  347.                   SetWindowTitles(mywindow,(UBYTE *)"",(UBYTE *) -1L);
  348.                   done(1);
  349.                }
  350.             }
  351.          }
  352.       }
  353.       if(rexxbit & getbits) {
  354.          while(rexxmessage = GetRexxMsg(rexx_host,0L)) {
  355.             if(Arg = GetRexxCommand(rexxmessage)) {
  356.                strcpy(p->line,(char *)Arg);
  357.                strcat(p->line,"\n");
  358.                ReplyRexxCommand(rexxmessage,0L,0L,0L);
  359.                goto cmd_exit;
  360.             }
  361.             else {
  362.                FreeRexxCommand(rexxmessage);
  363.             }
  364.          }
  365.       }
  366.       if(getbits & keybit) {
  367.          WaitIO((struct IORequest *)Con_Read);
  368.          ch = ichar;
  369.          Con_Read->io_Data = (APTR)&ichar;
  370.          Con_Read->io_Command = CMD_READ;
  371.          Con_Read->io_Length = 1;
  372.          SendIO((struct IORequest *)Con_Read);
  373.          if(ch == '\033') {
  374.             if(p == cport)ttputs("getdatCON\n");
  375.             else          ttputs("getdatTNC\n");
  376.          }
  377.          if(charf(ch)) {
  378. cmd_exit:
  379.             if(timerbit & getbits) {
  380.                WaitIO((struct IORequest *)&timermsg);
  381.             }
  382.             else {
  383.                if(curmin)cantimer();
  384.             }
  385.             return(true);
  386.          }
  387.       }
  388.       if(timerbit & getbits) {
  389.          WaitIO((struct IORequest *)&timermsg);
  390.          *cp = 0;
  391.          if(!(p->mode & idle))p->mode = timeout;
  392.          return (true);
  393.       }
  394.    }
  395. }
  396. charf(s)
  397. unsigned char s;
  398. {
  399.    register unsigned char ch;
  400.    register char *q,*r;
  401.    register int i;
  402.    PORTS *p;
  403.  
  404.    p = port;
  405.    ch = s;
  406.    /* Ignore characters with high order bit set...they tie up the TNC */
  407.    if(ch > 0177)return(0);
  408.    *cp = ch;
  409.    if((cp == p->line + linelen - 2) || (ch == '\r')) {
  410. do_lf:
  411.       if(ch == '\r')*cp = '\n';
  412.       *++cp = 0;
  413.       if(p->flags & p_echo)outchar('\n');
  414.       return(1);
  415.    }
  416.    if((ch >= ' ') && (ch <= 0176)) {
  417.       /*
  418.          Do justification for local user.
  419.       */
  420.       if(p->dev == p_console) {
  421.          if(ch == ' ') {
  422.             s_pos = x_pos;
  423.             /* If the space is at exactly the point we would have justified
  424.                the line then fake a CR anyway
  425.             */
  426.             if(x_pos == MAXLEN) {
  427.                ch = '\r';
  428.                *saveword = 0;
  429.                goto do_lf;
  430.             }
  431.          }
  432.          else {
  433.             /* It's not a space ... should we do the justify?
  434.             */
  435.             if(x_pos == MAXLEN) {
  436.                /* This word can't be longer than MAXJUST or we just leave
  437.                   it alone and let them mess up the line
  438.                */
  439.                if((i = (MAXLEN - s_pos)) < MAXJUST) {
  440.                   q = saveword;
  441.                   r = &p->line[s_pos+1];
  442.                   do {
  443.                      *q++ = *r++;
  444.                      ttputs("\b \b");
  445.                   }while(--i);
  446.                   *q = 0;
  447.                   cp = &p->line[s_pos];
  448.                   ch = '\r';
  449.                   goto do_lf;
  450.                }
  451.             }
  452.          }
  453.       }
  454.       x_pos++;
  455.       if (p->flags & p_echo) ttputc(ch);
  456.       cp++;
  457.       return(0);
  458.    }
  459.    switch(ch) {
  460.    default:
  461.       break;
  462.    case 26:    /* Control - Z */
  463.       cp++;
  464.       x_pos++;
  465.       break;
  466.    case '\t':
  467.       if(p->flags & p_echo) ttputc(ch);
  468.       s_pos = x_pos;
  469.       x_pos++;
  470.       cp++;
  471.       break;
  472.    case '\b':
  473.       if(cp > p->line) {
  474.          cp--;
  475.          if(p->flags & p_echo) ttputs("\b \b");
  476.          x_pos--;
  477.          /* If they wipe out a space we've got to find the previous one */
  478.          if(*cp == ' ') {
  479.             r = cp-1;
  480.             while(r > p->line) {
  481.                if(*r == ' ') break;
  482.                r--;
  483.             }
  484.             s_pos = r - p->line;
  485.          }
  486.  
  487.       }
  488.       break;
  489.  
  490.    case '\n':
  491.       if(cp is p->line) {
  492.          *cp = '\0';
  493.          return(1);
  494.       }
  495.       break;
  496.    }
  497. #ifdef OLD_CODE
  498.    switch(*cp) {
  499.    default:
  500.       if (p->flags & p_echo) outchar(*cp);
  501.       cp++;
  502.       break;
  503.    case '\b':
  504.       if(cp > p->line) {
  505.          cp--;
  506.          if(p->flags & p_echo)outstr("\b \b");
  507.       }
  508.       break;
  509.  
  510.    case '\n':
  511.       if(cp is p->line) {
  512.          *cp = '\0';
  513.          return(1);
  514.       }
  515.       break;
  516.    case '\0' :    /* Ignore most ctl char */
  517.    case ctl_c:    /* Ignore most ctl char */
  518.    case ctl_v:    /* Ignore most ctl char */
  519.    case '\033':
  520.       break;
  521.    }
  522. #endif
  523.    return(0);
  524. }
  525.  
  526. /* replace waitcmd from mbtnc to reduce busy waits */
  527. /* NOT NEEDED in SYSOP */
  528. waitcmd(x)
  529. int x;
  530. {
  531. }
  532.  
  533.  
  534.  
  535. /* Replace the pause routine so that it can be used with TNC as well
  536.    as the console. If routine times out after 2 minutes then it will
  537.    return 'Q'.
  538.    The test for optflags[2] allows the SYSOP to specify whether the system
  539.    will pause after 20 lines of output to the user.
  540. */
  541. pause()
  542. {
  543.  
  544.    register char ch,*q;
  545.    ULONG class,waitbits;
  546.    USHORT code;
  547.    if(arexx_port)return(' ');
  548.    if (port->user->state & u_pause) return ' ';
  549.    /* If remote user has interrupted, then return a 'Q' anyway */
  550.    if(!optflags[2] && ((port->mode != local) || (pt_flag)))return(' ');
  551.  
  552.    q = &tmpstr[0];
  553.    prtx(pausemsg);
  554.    if(port->mode != local)outchar('\n');
  555.    settimer(120);   /* set timeout timer  */
  556.    waitbits = windbit | timerbit | keybit;
  557.    while(1)  {
  558.       getbits = Wait(waitbits);
  559.       if(windbit & getbits) {
  560.          while(NewMessage =
  561.                      (struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
  562.             class = NewMessage->Class;
  563.             code = NewMessage->Code;
  564.             ReplyMsg((struct Message *)NewMessage);
  565.             if(class == CLOSEWINDOW) {
  566.                /* say a fond farewell, don't ask fer sure? */
  567.                if(done_flag) {
  568.                   if(timerbit & getbits) {
  569.                      WaitIO((struct IORequest *)&timermsg);
  570.                   }
  571.                   else {
  572.                      cantimer();
  573.                   }
  574.                   SetWindowTitles(mywindow,(UBYTE *)"",(UBYTE *) -1L);
  575.                   done(1);
  576.                }
  577.             }
  578.          }
  579.       }
  580.       if(getbits & keybit) {
  581.          WaitIO((struct IORequest *)Con_Read);
  582.          ch = toupper(ichar);
  583.          Con_Read->io_Data = (APTR)&ichar;
  584.          Con_Read->io_Command = CMD_READ;
  585.          Con_Read->io_Length = 1;
  586.          SendIO((struct IORequest *)Con_Read);
  587.          if(timerbit & getbits) {
  588.             WaitIO((struct IORequest *)&timermsg);
  589.          }
  590.          else {
  591.             cantimer();
  592.          }
  593.          outchar('\n');
  594.          return(ch);
  595.       }
  596.       /* check for timeout */
  597.       if(timerbit & getbits) {
  598.          WaitIO((struct IORequest *)&timermsg);
  599.          return('Q');
  600.       }
  601.    }
  602. }
  603.  
  604. /* Null routines from the mblog.c file.
  605.    SYSOP does not do any logging whatever (there's also a small fix in
  606.    mbinit.c to turn off all the logging flags).
  607.    It also does no monitoring.
  608. */
  609. /* Define the length of a heard item. It is easier to do this and have
  610.    mbinit allocate a very small heard list than to have another version
  611.    of mbinit just for one small change.
  612. */
  613. char *lgfile = 0,*monfile = 0,*hrdfile = 0;
  614. int hrdmax = 1;
  615. char fbb_direction;
  616. /* Dummy fbb forwarding */
  617. char *mbvers,*fbbvers;
  618. fbbfwd()
  619. {
  620. }
  621.